function BackstabDamage takes nothing returns nothing
	local unit target = GetEnumUnit()
	local location targetLocation = GetUnitLoc(target)
	local real angle = AngleBetweenPoints(udg_TempCasterLocation , targetLocation)
	local real targetBackFacing = 0.0
	local integer windWalkWeakLevel = GetUnitAbilityLevel(target , 'A01Z')
	local real realDamage = udg_TempDamage * (1.0 + I2R(windWalkWeakLevel) * 0.3)
	//--
	if (IsUnitEnemy(target , udg_TempPlayer) and IsUnitInRangeLoc(target , udg_TempCasterLocation , udg_TempRadius) and not IsUnitType(target , UNIT_TYPE_STRUCTURE) and GetUnitState(target , UNIT_STATE_LIFE) > 0.0 and WithinAngle(angle , udg_TempCastAngle , udg_TempEffectiveAngle)) then
		set udg_TempHitCount = udg_TempHitCount + 1
		set targetBackFacing = AngleNormalize(GetUnitFacing(target) + 180.0)
		if WithinAngle(AngleNormalize(angle + 180.0) , targetBackFacing , 120.0) then
			set realDamage = realDamage * (1.0 + udg_TempExtraRatio)
			set udg_TempBackstabCount = udg_TempBackstabCount + 1
		endif
		call UnitDamageTarget(udg_TempCaster , target , realDamage , true , false , ATTACK_TYPE_NORMAL , DAMAGE_TYPE_COLD , WEAPON_TYPE_METAL_MEDIUM_SLICE)
	endif
	call RemoveLocation(targetLocation)
	//--
	set target = null
	set targetLocation = null
endfunction

function BackstabActionEffect takes nothing returns nothing
	local timer delayTimer = GetExpiredTimer()
	local integer timerId = GetHandleId(delayTimer)
	local real mastery = 0
	local unit caster = LoadUnitHandle(udg_HT , timerId , 0)
	local integer abilityLevel = GetUnitAbilityLevel(caster , 'A01W')
	local real masteryGain = 0.0
	local real daggerDamage = LoadReal(udg_ItemDataHashTable , GetHandleId(LoadItemHandle(udg_HT , timerId , 2)) , StringHash("WEAPON_DAMAGE")) //  10  15  25  50
	//--
	set udg_TempCaster = caster
	set udg_TempPlayer = GetOwningPlayer(udg_TempCaster)
	set mastery = LoadReal(udg_UnitDataHashTable , GetHandleId(udg_TempCaster) , StringHash("BACKSTAB_MASTERY"))
	set udg_TempDamage = 20.0 + daggerDamage * 0.1 * mastery
	set udg_TempHitCount = 0
	set udg_TempBackstabCount = 0
	set udg_TempExtraRatio = 0.25 * I2R(abilityLevel)
	set udg_TempRadius = 130.0
	set udg_TempEffectiveAngle = 100.0
	set udg_TempCasterLocation = GetUnitLoc(udg_TempCaster)
	set udg_TempSpellTargetLocation = LoadLocationHandle(udg_HT , timerId , 1)
	set udg_TempCastAngle = AngleBetweenPoints(udg_TempCasterLocation , udg_TempSpellTargetLocation)
	call RemoveLocation(udg_TempSpellTargetLocation)
	call For(GetUnitsInRangeOfLocMatching(udg_TempRadius + 70.0 , udg_TempCasterLocation , null) , function BackstabDamage)
	set masteryGain = 0.5 + 0.4 * I2R(udg_TempHitCount) + 2.0 * I2R(udg_TempBackstabCount)
	call UnitUsedAbilityWithDelta(caster , 'A01W' , masteryGain)
	
	call RemoveLocation(udg_TempCasterLocation)
	call PauseTimer(delayTimer)
	call FlushChildHashtable(udg_HT , timerId)
	call DestroyTimer(delayTimer)
	//--
	set delayTimer = null
	set caster = null
endfunction

function BackstabAction takes nothing returns nothing
	local timer delayTimer = CreateTimer()
	local integer timerId = GetHandleId(delayTimer)
	//--
	call SaveUnitHandle(udg_HT , timerId , 0 , GetTriggerUnit())
	call SaveLocationHandle(udg_HT , timerId , 1 , GetSpellTargetLoc())
	call SaveItemHandle(udg_HT , timerId , 2 , GetWeaponOfType(GetTriggerUnit() , StringHash("DAGGER")))
	call TimerStart(delayTimer , 0.4 , false , function BackstabActionEffect)
	call UnitPlayAnimation(GetTriggerUnit() , 28 , 1.5 , 0.6)
	//--
	set delayTimer = null
endfunction

function Trig_BackstabTryActions takes nothing returns nothing
	if GetSpellAbilityId() == 'A01W' then
		call BackstabAction()
	endif
endfunction

function InitTrig_Backstab takes nothing returns nothing
	local hashtable masteryTable = InitHashtable()
	local integer abilityId = 'A01W'
	//--	
	call SaveInteger(udg_AbilityDataHashTable , abilityId , StringHash("NEXT_ABILITY") , 'A01X')
	call SaveInteger(udg_AbilityDataHashTable , abilityId , StringHash("HOTKEY") , StringHash("E"))
	call SaveInteger(udg_AbilityDataHashTable , abilityId , StringHash("MASTERY_ID") , StringHash("BACKSTAB_MASTERY"))
	call SaveStr(udg_AbilityDataHashTable , abilityId , StringHash("NAME") , "背刺")
	call SaveInteger(udg_AbilityDataHashTable , abilityId , StringHash("MAX_LEVEL") , 3)
	call SaveHashtableHandle(udg_AbilityDataHashTable , abilityId , StringHash("LEVEL_MASTERY_TABLE") , masteryTable)
	call SaveReal(masteryTable , 1 , 0 , 30.0)
	call SaveReal(masteryTable , 2 , 0 , 70.0)
	call SaveReal(masteryTable , 3 , 0 , 120.0)
	
	set gg_trg_Backstab = CreateTrigger()
	call TriggerRegisterPlayerForceUnitEvent(gg_trg_Backstab , EVENT_PLAYER_UNIT_SPELL_EFFECT )
	call TriggerAddAction(gg_trg_Backstab , function Trig_BackstabTryActions)
	//--
	set masteryTable = null
endfunction